package de.slothsoft.wasbinich.core.database.webservice;

import java.io.Serializable;
import java.util.Date;

import de.slothsoft.wasbinich.core.database.DatabaseException;

public abstract class AbstractOAuth2Authenticator {

    protected final OAuth2Authenticator oAuth2Authenticator;
    protected Token currentToken;

    public AbstractOAuth2Authenticator(RestCommunicator restCommunicator) {
	this.oAuth2Authenticator = new OAuth2Authenticator(restCommunicator);
    }

    public void invalidateToken() {
	this.currentToken = null;
    }

    public Token getToken() throws DatabaseException {
	Token token = getExistingAccessToken();
	if (token == null) {
	    token = getAccessTokenFromRefreshToken();
	}
	if (token == null) {
	    token = getAccessTokenFromUser();
	}
	this.currentToken = token;
	return token;
    }

    protected Token getExistingAccessToken() {
	if (this.currentToken == null)
	    return null;
	if (this.currentToken.expireDate == null || this.currentToken.expireDate.before(new Date()))
	    return null;
	return this.currentToken;
    }

    protected Token getAccessTokenFromRefreshToken() throws DatabaseException {
	if (this.currentToken != null && this.currentToken.refreshToken != null)
	    return this.oAuth2Authenticator.getAccessToken(this.currentToken.refreshToken);
	return null;
    }

    protected abstract Token getAccessTokenFromUser() throws DatabaseException;

    /*
     * 
     */

    public static class Token implements Serializable {

	public static final long serialVersionUID = 6404297107770195857L;

	public String accessToken;
	public String refreshToken;
	public Date expireDate;

	public Token() {
	    super();
	}

	public Token(String accessToken, String refreshToken, Date expireDate) {
	    this.accessToken = accessToken;
	    this.refreshToken = refreshToken;
	    this.expireDate = expireDate;
	}

	@Override
	public String toString() {
	    return "accessToken = " + this.accessToken + ", refreshToken = " + this.refreshToken + ", expireDate = " //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		    + this.expireDate;
	}

    }

    /*
     * 
     */

    public static class User implements Serializable {

	private static final long serialVersionUID = -7881588023792422081L;

	public String id;
	public String password;

	public User(String id, String password) {
	    this.id = id;
	    this.password = password;
	}

    }
}
